package com.espirit.eap.sa;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ManyToOne;
import javax.persistence.Transient;

import org.apache.commons.lang.StringUtils;
import org.hibernate.annotations.BatchSize;

import com.espirit.eap.ICheckModelDuplicateInfo;
import com.espirit.eap.annotation.DomainModel;
import com.espirit.eap.annotation.ModelDisplayProperty;
import com.espirit.eap.manager.Department;
import com.espirit.eap.pagelayout.AvabButton;
import com.espirit.eap.relationship.Party;
import com.espirit.eap.relationship.PartyRelationship;
import com.googlecode.cswish.security.auth.UserInfo;

@DomainModel
@Entity(name="com.espirit.eap.sa.User")
@ModelDisplayProperty("code")
@BatchSize(size=10)
public class User extends Party implements UserInfo,ICheckModelDuplicateInfo {
	
	private static final long serialVersionUID = 6941368790239123213L;

	private LoginUser loginUser;
	
	// transient
	private String password1;
	private String password2;
	private User users;
	
	private Employee employee;
	
	
	@ManyToOne(targetEntity = LoginUser.class, fetch=FetchType.EAGER, cascade=CascadeType.ALL)
	public LoginUser getLoginUser() {
		return loginUser;
	}

	public void setLoginUser(LoginUser loginUser) {
		this.loginUser = loginUser;
	}

	
	@Transient
	public String getPassword1() {
		return password1;
	}

	public void setPassword1(String password1) {
		this.password1 = password1;
	}
	
	@Transient
	public String getPassword2() {
		return password2;
	}

	public void setPassword2(String password2) {
		this.password2 = password2;
	}
	
	public void setUsers(User user){
		this.users = user;
	}
	@Transient
	public User getUsers(){
		return users;
	}
	
	public boolean permit(com.espirit.eap.pagelayout.Model model,AvabButton ab){
		return permit(model,ab.getName());
	}
	public boolean permit(com.espirit.eap.pagelayout.Model model,String buttonName){
		return false;
	}
	

	@Transient
	@Override
	public String getLoginId() {
		return String.valueOf(getId());
	}
	
	@Transient
	@Override
	public String[] getRoleIds() {
		return null;
	}

	private final static String[] gatherProperties = new String[]{"code"};
	@Override
	public String[] gatherProperties() {
		return gatherProperties;
	}
	
	@Transient
	public Collection<Integer> getAllRelatedUsers(){
		Collection<Integer> ids = new HashSet<Integer>();
		for(Department department : getDepartments()){
			ids.addAll(department.getAllUserIds());
		}
		return ids;
	}

	@ManyToOne(fetch=FetchType.LAZY)
	public Employee getEmployee() {
		return employee;
	}

	public void setEmployee(Employee employee) {
		this.employee = employee;
	}
	
	
	@Transient
	public String getDescDepartmentIds(){
		if (descDepartmentIds == null){
			StringBuilder sb = new StringBuilder();
			for(Department department : getDepartments()){
				sb.append(department.getId().toString()).append(",");
				Set<Department> depts = department.getDescendentChildren(Department.class);
				if (depts != null){
					for(Department dept : depts){
						sb.append(dept.getId().toString()).append(",");
					}
				}
			}
			
			if (sb.length() > 0) {
				descDepartmentIds = sb.substring(0, sb.length() -1);
			} else {
				descDepartmentIds = "";
			}
		}
		return descDepartmentIds;
	}
	
	private Set<Integer> descDepartmentIdList;
	@Transient
	public Set<Integer> getDescDepartmentIdList() {
		if (descDepartmentIdList == null) {
			String ids = getDescDepartmentIds();
			if (!StringUtils.isEmpty(ids)){
				String[] idArray = ids.split(",");
				descDepartmentIdList = new HashSet<Integer>(idArray.length);
				for(String id : idArray ){
					descDepartmentIdList.add(Integer.valueOf(id));
				}
			}
		}
		return descDepartmentIdList;
	}

	public void setDescDepartmentIds(String descDepartmentIds) {
		this.descDepartmentIds = descDepartmentIds;
	}
	
	@Transient
	protected Set<Department> getDepartments() {
		Set<Department> deparments = new HashSet<Department>();
		if (getParents() != null) {
			for(PartyRelationship prs : getParents()){
				if (prs.getPartyParent() instanceof Department){
					deparments.add((Department)prs.getPartyParent());
				}
			}
		} 
//		if (this instanceof Department){
//			if (!deparments.contains(this)){
//				deparments.add((Department)this);
//			}
//		}
		return deparments;
	}
	
	@Transient
	public String getDepartmentIds() {
		if (departmentIds == null) {
			List<Integer> departmentIdList = getDepartmentIdList();
			departmentIds = StringUtils.join(departmentIdList, ','); 
		}
		return departmentIds;
	}
	
	@Transient
	public List<String> getDeptNameList(){
		List<String> departmentNameList = new ArrayList<String>();
		for(Department department : getDepartments()){
			departmentNameList.add(department.getName());
		}
		return departmentNameList;
	}
	
	private List<Integer> departmentIdList;
	@Transient
	public List<Integer> getDepartmentIdList() {
		if (departmentIdList == null) {
			departmentIdList = new ArrayList<Integer>();
			
			for(Department department : getDepartments()){
				departmentIdList.add(department.getId());
			}
		}
		return departmentIdList;
	}
	
	public void setDepartmentIds(String departmentIds) {
		this.departmentIds = departmentIds;
		String[] ids = StringUtils.split(departmentIds, ',');
		departmentIdList = new ArrayList<Integer>(ids.length);
		for (String id : ids) {
			departmentIdList.add(new Integer(id));
		}
	}
	private String descDepartmentIds;
	private String departmentIds;

}